package com.qjs.smterp.web.beans;

import java.io.Serializable;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;

import com.qjs.smterp.dto.ChangePassword;
import com.qjs.smterp.model.Users;
import com.qjs.smterp.types.UserRole;
import com.qjs.smterp.services.SecurityServices;
import com.qjs.smterp.utils.MD5;
import com.qjs.smterp.web.utils.FacesContextUtils;

@ManagedBean(name = "mbAuthentication")
@SessionScoped
public class MbAuthentication implements Serializable {
	private static final long serialVersionUID = 1L;

	public static final String AUTH_KEY = "app.user";

	private static final String DEFAULT_PASSWORD = "12345678";

	@ManagedProperty("#{securityServices}")
	private SecurityServices securityServices;

	private Users user;

	private String encryptPass;

	private ChangePassword changePassword;

	private int loginTime;

	@PostConstruct
	protected void init() {
		user = new Users();
		changePassword = new ChangePassword();
		loginTime = 0;
	}

	public boolean isLoggedIn() {
		return FacesContext.getCurrentInstance().getExternalContext()
				.getSessionMap().get(AUTH_KEY) != null;
	}

	public String doLogin() {
		String plainTextPassWord = user.getPwd();
		this.encryptPass = MD5.MD5Encode(plainTextPassWord);
		user = securityServices.findUsers(user.getLogin());
		if (user != null) {
			if (!user.getEnabled()) {
				String msg = String
						.format("The user account { %s } have been clocked. Please contact with system admin.",
								user.getLogin());
				FacesContextUtils.addErrorExceptionMessage(msg);
				return null;
			} else if (this.encryptPass.equals(user.getPwd())) {
				FacesContext.getCurrentInstance().getExternalContext()
						.getSessionMap().put(AUTH_KEY, user);
				loginTime = 0;
				if (DEFAULT_PASSWORD.equals(plainTextPassWord)) {
					String warningStr = "SYSTEM WARNING: You are logging to system using default password. "
							+ "For preventing security issues, Please change new password.";
					FacesContextUtils.addErrorExceptionMessage(warningStr);
					return "/faces/admin/changePass.xhtml";
				} else {
					return "/faces/main.xhtml";
				}

			} else {
				if (++loginTime >= 3) {
					user.setEnabled(false);
					securityServices.updateUsers(user);
					String msg = String
							.format("The user account { %s } has logged in fail %s times. This account have been clocked by system.",
									user.getLogin(), loginTime);
					FacesContextUtils.addErrorExceptionMessage(msg);
					loginTime = 0;
					return null;
				} else {
					FacesContextUtils
							.addErrorExceptionMessage("Login fail! Wrong password.");

					return null;
				}
			}
		} else {
			String message = new String(
					"The user account is not exist in the system.");
			FacesContextUtils.addErrorExceptionMessage(message);
			loginTime = 0;
			return null;
		}

	}

	public String logout() {
		Map<String, Object> sessionMap = FacesContext.getCurrentInstance()
				.getExternalContext().getSessionMap();
		sessionMap.clear();
		return "/loginPage.xhtml";
	}

	public String doChangePass() {
		String oldPassEncrypt = MD5.MD5Encode(changePassword.getOldPass());
		String newPass = changePassword.getNewPass();
		String confirmNewPass = changePassword.getConfirmNewPass();
		if (this.encryptPass.equals(oldPassEncrypt)) {
			if (newPass.length() < 8) {
				FacesContextUtils
						.addErrorExceptionMessage("The new password is must more than 8 character.");
				return null;
			}
			if (confirmNewPass.length() < 8) {
				FacesContextUtils
						.addErrorExceptionMessage("The confirm new password is must more than 8 character.");
				return null;
			}
			if (newPass.equals(confirmNewPass)) {
				user.setPwd(MD5.MD5Encode(changePassword.getNewPass()));
				securityServices.updateUsers(user);
				return logout();
			} else {
				FacesContextUtils
						.addErrorExceptionMessage("The new password and confirm new password are not equal.");
			}
		} else {
			FacesContextUtils
					.addErrorExceptionMessage("The old password is not exist.");
		}
		return null;

	}

	public void setSecurityServices(SecurityServices securityServices) {
		this.securityServices = securityServices;
	}

	public Users getUser() {
		if (user == null) {
			user = new Users();
		}
		return user;
	}

	public void setUser(Users user) {
		this.user = user;
	}

	public boolean isAdminRole() {
		return user.getRole().equals(UserRole.ADMIN.name());
	}

	public ChangePassword getChangePassword() {
		if (changePassword == null) {
			changePassword = new ChangePassword();
		}
		return changePassword;
	}

	public void setChangePassword(ChangePassword changePassword) {
		this.changePassword = changePassword;
	}

	public String getEncryptPass() {
		return encryptPass;
	}

	public void setEncryptPass(String encryptPass) {
		this.encryptPass = encryptPass;
	}

	public int getLoginTime() {
		return loginTime;
	}

	public void setLoginTime(int loginTime) {
		this.loginTime = loginTime;
	}

}
